/*
	Copyright (C) 2008 by Jean-François Geyelin
	jfgeyelin@gmail.com

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the
	Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/


#include "ReplayHandler.h"
#include "StreamHandler.h"
#include "safeFileIO.h"
#include "settings.h"
#include "readMap.h"
#include "checkSum.h"


ReplayHandler::ReplayHandler(void) {
    data = NULL;
    size = 0;
    mapName = "";
    seed = 0;
}

ReplayHandler::~ReplayHandler(void) {
    TEST_EXECUTION()
    if (data!=NULL)
    free(data);
}

void ReplayHandler::readTempFile(const char *path) {
    if (data!=NULL) {
        free(data);
        data = NULL;
    }

    FILE *f = fopen_safe((const char *)path,"rb");
    if (!f) {
        LOG_ERROR("failed to open the file containing the replay (%s).\n",path);
        return;
    }

    long l;

    TEST_EXECUTION()

    /* Reads the checksum */
    uint32_t checkSum;
    StreamHandler::readLong(f,&l);
    checkSum = (uint32_t)l;

    /* Reads seed */
    StreamHandler::readLong(f,&l);
    seed = l;

    /* Reads map number */
    StreamHandler::readLong(f,&l);
    std::string m[100];
    readMap(m);

    mapName = m[l];
    /* Reads nickname */
    TEST_EXECUTION()
    StreamHandler::readString(f,&nickName);

    /* Reads the replay */
    TEST_EXECUTION()
    size = 0;
    unsigned int bufferSize = 1000;
    data = (unsigned char*)malloc(bufferSize);

    unsigned char c;
    while (StreamHandler::readNextCharacterInFile(f,&c)) {
        data[size] = c;
        size++;
        if (size>bufferSize-5) {
            bufferSize*=2;
            data = (unsigned char*)realloc(data,bufferSize);
        }
    }
    TEST_EXECUTION()
    if (checkSum != checkSumCalculator(data,size))
    LOG_ERROR("checksum are different.\n");

    fclose(f);
}

int ReplayHandler::getSeed(void) {
    return seed;
}

std::string ReplayHandler::getMapName(void) {
    return mapName;
}

unsigned char *ReplayHandler::getData(size_t *size_) {
    *size_ = size;
    return data;
}


bool postFileToServer(void);

void ReplayHandler::writeTempFile(int seed_, std::string mapName_, unsigned char *data_, size_t size_) {
    FILE *f = fopen_safe("record.txt","wb");
    if (!f) {
        LOG_ERROR("failed to open temporary file to store the replay\n");
        return;
    }
    else {
        PRINTF("opened temporary file to store the replay\n");
    }

    /* Writes a checksum */
    StreamHandler::writeInt(f,checkSumCalculator(data_, size_));
    /* Writes the seed */
    StreamHandler::writeInt(f,seed_);
    /* Writes the map number */
    StreamHandler::writeInt(f,getMapNumberFromName(mapName_));
    /* Writes the nickName */


    Settings settings;
    loadSettings(&settings);


    StreamHandler::writeString(f,settings.playerName);
    /* Writes the replay data */
    unsigned int i;
    for (i=0;i<size_;i++) {
        StreamHandler::writeNextCharacterInFile(f,data_[i]);
    }
    fclose(f);
    PRINTF("finished writing the file\n");

}

void ReplayHandler::writeTempFile(int seed_, std::string mapName_, RLEHandler rleHandler) {
    size_t size_;
    unsigned char *data_ = rleHandler.getData(&size_);
    writeTempFile(seed_, mapName_, data_, size_);
}

void ReplayHandler::setNickName(std::string nickName_) {
    nickName = nickName_;
}

std::string ReplayHandler::getNickName(void) {
    return nickName;
}

